package ysother

import (
	"context"
	"fmt"
	"gitee.com/kmyss/gf-ex/yslog"
	"gitee.com/kmyss/gf-ex/ysutils"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gcfg"
	"github.com/gogf/gf/v2/os/gfile"
	"github.com/gogf/gf/v2/util/gutil"
)

type IAdapterFile interface {
	gcfg.Adapter

	GetFilePath(...string) (string, error)
}

func DebugConfig(ctx context.Context, name ...string) {

	if !ysutils.IsDebugMode() {
		return
	}

	cfg := g.Cfg(name...)
	if cfg.Available(ctx) {
		yslog.Debug("配置文件读取参数如下：")
		g.DumpTo(yslog.GetWriter(), cfg, gutil.DumpOption{WithType: false, ExportedOnly: false})
		yslog.Debug("配置文件内容如下：")
		g.DumpTo(yslog.GetWriter(), cfg.MustData(ctx), gutil.DumpOption{WithType: false, ExportedOnly: false})
	} else {
		yslog.Debug("没有配置文件")
	}
}

func ShowConfigPath(name ...string) {

	adapter := g.Cfg(name...).GetAdapter().(IAdapterFile)

	path, err := adapter.GetFilePath()
	if err != nil {
		yslog.Print("未找到配置文件")
	} else {
		yslog.Print("当前配置文件为：", path)
	}
}

func CopyConfig(path string) error {
	dstPath := gfile.Abs(ysutils.DefaultRunConfig)

	_ = BackFile(dstPath)

	yslog.Printf("* 拷贝 %s 到 %s", gfile.Basename(path), gfile.Basename(dstPath))
	err := gfile.Copy(gfile.Abs(path), dstPath)
	if err != nil {
		return err
	}

	return nil
}

type writeConfigInput struct {
	path    string // 文件路径
	name    string // 配置名
	encoder iCfgEncoder
}

func writeConfig(ctx context.Context, in writeConfigInput) error {

	data, err := g.Cfg(in.name).Data(ctx)
	if err != nil {
		return gerror.New(fmt.Sprintf("无法读取 %s 配置！%s", in.name, err.Error()))
	}

	encodeData, err := in.encoder.encode(data)
	if err != nil {
		return gerror.New(fmt.Sprintf("配置转换 %s 失败！%s", in.encoder.name(), err.Error()))
	}

	filePath := gfile.Join(in.path, in.name+"."+in.encoder.name())

	// 备份原来的文件
	_ = BackFile(filePath)
	err = gfile.PutBytes(filePath, encodeData)
	if err != nil {
		return gerror.New(fmt.Sprintf("写入 %s 失败！%s", filePath, err.Error()))
	}

	return nil
}

func WriteTomlConfig(ctx context.Context, path string, name ...string) error {
	n := ""
	if len(name) > 0 {
		n = name[0]
	}
	return writeConfig(ctx, writeConfigInput{
		path:    path,
		name:    n,
		encoder: &tomlEncode{},
	})
}

func WriteYamlConfig(ctx context.Context, path string, name ...string) error {
	n := ""
	if len(name) > 0 {
		n = name[0]
	}
	return writeConfig(ctx, writeConfigInput{
		path:    path,
		name:    n,
		encoder: &yamlEncode{},
	})
}
